//== GAIA ============================================================================

//== BEGINNING OF CODE ===============================================================

#include "sagittarius/core/SagittariusCore.h"

#if !SAGITTARIUS_LXALPHA_USE_GMP
#include "sagittarius/unicode/CUnicode.h"
#else
#include "sagittarius/unicode/GMPUnicode.h"
#include "sagittarius/io/io.h"
#endif
#include "sagittarius/lexer/lexx.h"

#include <stdio.h>
#include <string.h>
#include <malloc.h>

#if LX_USE_POOLALLOC
extern lx_segcontext lx_myseg;
#endif

int main(int argc, char* argv[])
{
    lexWork* lw;
	int result;
	#if !SAGITTARIUS_LXALPHA_USE_GMP
        UnicodeCChar* ubuf;
    #else
        GMPUnicodeChar* ubuf;
    #endif

    //const char* buf = "letter = [a-b]|[A-B]\nidentifier = (letter|_)*";
    //const char* buf = "letter = ^([A-P]|[S-Z])&[C-Z]\n\0identifier = (letter|_)*";
    //const char* buf = "letter = ^([A-P]|[S-Z])\n\0identifier = (letter|_)*";
    //const char* buf = "letter = (a|b)*(b|c)\n\0identifier = (letter|_)*";
    //const char* buf = "letter = (a|𝜀)(ac|(ad|ae))\n\0identifier = (letter|_)*";
    //const char* buf = "letter = (((qh|ae)|(ad|la))|ac)\n\0identifier = (letter|_)*";
    //const char* buf = "letter = (((qh|ae)|(a|la))|ac)\n\0identifier = (letter|_)*";
    //const char* buf = "letter = (((事h|ae)|(a|la))|ac)\n thing = ab\n\0identifier = (letter|_)*";
    //const char* buf = "letter = (((事h|ae)|(aa*|la))|ac) -> stop\nthing = ab|a(c|f) -> stop\nzzz = ay|ax -> stop";
    //const char* buf = "letter = (((事h|ae)|(aa*|la))|ac) -> stop\nthing = [ajk]b|a(d|f) -> stop\nzzz = ay|ax -> stop\nguido = ab*cda*";
        const char* buf = "ws = [ \\n] -> reset\nletter = (((事h|ae)|(aa*|la))|ac) -> stop\nthing = [ajk]b|a(d|f) -> stop\nzzz = ay|ax -> stop\nguido = ab*cda* -> stop";
    size_t data_size = strlen(buf);
    //printf("length of input stream: %lu\n", data_size);
    
    //create buffer for unicode values
    #if !SAGITTARIUS_LXALPHA_USE_GMP
        ubuf = malloc((data_size+1)*sizeof(UnicodeCChar)); //size+1 is important for storing the null-terminating value
        assert(ubuf && "Unable to allocate memory");
    #else
        ubuf = sg_bignum_create_buf(data_size+1);
        assert(ubuf && "Unable to allocate memory");
    #endif
    
    //convert
    #if !SAGITTARIUS_LXALPHA_USE_GMP
        result = UTF8_ConvertBuffer(buf, ubuf);
    #else
        result = UTF8_GMPConvertBuffer(buf, ubuf);
    #endif
    if(result < 0)
    {
        fprintf(stderr, "Failed to convert buffer, routine returned with code %d\n", result);
        free(ubuf);
        return -1;
    }
    
    /*printf("Unicode buffer:\n");
    #if !SAGITTARIUS_LXALPHA_USE_GMP
        printUnicodeBuf(ubuf);
    #else
        sg_writeGMPUStr(1, ubuf);
    #endif
    printf("\n\n");*/
    
    //Do parsing
#if LX_USE_POOLALLOC
    lx_initsegctx(&lx_myseg);
    lx_initsegctx(&lx_tmpseg);
    lx_segstack_push(&lx_myseg);
#endif
    lw = golex(ubuf);
    //dump_radix_node(1, lw->tab.r, 0);
    finalize_lex(lw);
    free(lw);
#if LX_USE_POOLALLOC
    lx_segstack_pop();
    lx_destroysegctx(&lx_myseg);
    lx_destroysegctx(&lx_tmpseg);
#endif
    
    //free buffer
    #if !SAGITTARIUS_LXALPHA_USE_GMP
        free(ubuf);
    #else
        LX_FREE_BUFFER(ubuf);
    #endif
    
    return 0;
}
